home *** CD-ROM | disk | FTP | other *** search
- /*
- * jmore.c
- * H.Ohkubo Oct. 4, 1992
- *
- * Modified Oct. 17, 1992 (Ver.0.02)
- * Modified 0ct. 22, 1992 (Ver.0.03)
- */
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/gfxbase.h>
- #include <workbench/startup.h>
- #include <functions.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <string.h>
- #include <ctype.h>
- #include "jctype.h"
- #include "openlib.h"
- #include "jFont.h"
- #include "jmore.h"
-
- struct Screen *Scrn = NULL;
- struct Window *Wind = NULL;
- struct RastPort *rport = NULL;
- int current_x, current_y;
-
- /* for backcscroll */
- USHORT current_line, top_line;
- SHORT count[USHRT_MAX];
-
- FILE *infile = NULL;
- char in_fname[FNAMELEN];
-
- struct TextFont *current_font = NULL;
- struct TextFont *resident_font[KATA + 1];
-
- BPTR olddir = NULL;
-
- int tabspc = TABSPC;
- BOOL regular = FALSE;
-
- struct MsgPort *jMorePort = NULL;
- struct jFontMsg fontMsg;
-
- /* prototypes */
- VOID print_file(VOID);
- int print_file_doit(VOID);
- VOID handle_ank_code(char *);
- VOID handle_kanji_code(char *);
- VOID handle_ctrl_code(int);
- char *strchr_r(char *, int);
- int keyin_loop(LONG *, int, char *);
- int print_message(char *);
- int handle_rawkey(VOID);
- int count_bytes(LONG *, int);
- VOID fseek_back(int);
- VOID init_myMsg(VOID);
- struct MsgPort *init_myport(VOID);
- struct TextFont *get_font(USHORT);
- struct TextFont *init_resident_font(VOID);
- VOID OpenScrnWind(VOID);
- FILE *fset(char *, char *);
- VOID clean_exit(char *, int);
- VOID usage(VOID);
- VOID get_startup(VOID);
- int set_startup_value(FILE *);
- char *my_getline(FILE *);
-
-
- VOID main(int argc, char *argv[])
- {
- if (argc == 0) {
- struct WBStartup *argmsg = (struct WBStartup *)argv;
- struct WBArg *wb_arg = argmsg->sm_ArgList;
-
- if (argmsg->sm_NumArgs < 2)
- exit(EXIT_FAILURE);
- if (wb_arg[1].wa_Lock != NULL)
- olddir = CurrentDir(wb_arg[1].wa_Lock);
- strcpy(in_fname, wb_arg[1].wa_Name);
- }
- else {
- if (argc < 2)
- usage();
- puts(COPYRIGHT);
- strcpy(in_fname, argv[1]);
- }
- infile = (FILE *)fset(in_fname, READ_BINARY);
-
- get_startup();
- init_myMsg();
- if (!OpenLib())
- clean_exit("No Library !", RETURN_FAIL);
- OpenScrnWind(); /* initialize jmore's screen */
-
- print_file();
-
- clean_exit(END_MESSAGE, RETURN_OK);
- }
-
-
- #define tabwidth(w) (tabspc*(w))
- #define tabalign(x, w) (((x)/tabwidth(w))*tabwidth(w) + tabwidth(w))
-
- char pool[BUFFSIZE + 1];
- char strbuff[STRBUFSIZE];
-
- VOID print_file(VOID)
- {
- current_font = init_resident_font();
- SetFont(rport, current_font);
- SetAPen(rport, 1);
- SetDrMd(rport, JAM2);
-
- current_x = Wind->BorderLeft;
- current_y = Wind->BorderTop + rport->TxBaseline;
- Move(rport, current_x, current_y);
-
- current_line = top_line = 0;
- count[current_line] = 0;
-
- while (print_file_doit())
- ;
- }
-
-
- int print_file_doit(VOID)
- {
- int len, remaining_size = 0, n;
- char *buff, *buff_tail, *head, *next_head, *p;
- #if 0
- char *line_head, *line_tail;
- #endif
-
- pool[0] = pool[BUFFSIZE] = LF;
- buff = pool + 1;
- buff_tail = pool + BUFFSIZE;
-
- head = buff;
- while ((len = fread(head, sizeof(char), buff_tail - head, infile)) > 0) {
- next_head = strchr_r(head + len - 1, LF) + 1;
- p = buff;
- while (p < next_head) {
- count[current_line]++;
- switch (nthmsctype(buff, p - buff)) {
- case CT_KJ2:
- handle_kanji_code(p);
- break;
- case CT_KJ1:
- break;
- case CT_ANK:
- handle_ank_code(p);
- break;
- case CT_ILGL:
- default:
- handle_ctrl_code((int)(*p));
- break;
- }
- p++;
- if (current_y > (Wind->Height - FONT_SIZE)) {
- switch (n = keyin_loop((VOID *)&p, p - buff, MORE_MES)) {
- case QUIT:
- return FALSE;
- break;
- case NORMAL:
- break;
- default: /* back scroll */
- fseek_back(len + remaining_size + n);
- return TRUE;
- break;
- }
- }
- }
- remaining_size = len - (next_head - head);
- memmove(buff, next_head, remaining_size);
- head = buff + remaining_size;
- }
- if ((n = keyin_loop((VOID *)&buff, 0, FILE_END_MES)) > 0) {
- fseek_back(len + remaining_size + n);
- return TRUE;
- }
-
- return FALSE;
- }
-
-
- VOID handle_ank_code(char *code)
- {
- if (current_font != resident_font[ANK]) {
- Text(rport, strbuff, strlen(strbuff));
- strbuff[0] = NUL;
- current_font = resident_font[ANK];
- SetFont(rport, current_font);
- current_x = rport->cp_x;
- }
-
- if ((current_x += current_font->tf_XSize) >= Wind->Width)
- handle_ctrl_code(LF);
- strncat(strbuff, code, sizeof(char));
- }
-
-
- VOID handle_kanji_code(char *p)
- {
- USHORT kanji;
- int fontnum;
- char code;
- struct TextFont *tf;
-
- kanji = (*(p - 1)&0xff)<<CHAR_BIT | *p&0xff;
- kanji = mstojis(kanji);
- fontnum = ((kanji>>CHAR_BIT)&0xff) - SPC;
- code = (char)(kanji&0xff);
-
- if (fontnum >= SYM1 && fontnum <= KATA) {
- if (regular && (isjalnum(kanji) || isjsymbol(kanji))) {
- int ascii_code;
-
- if ((ascii_code = jistoascii(kanji))) {
- tf = resident_font[ANK];
- code = (char)ascii_code;
- }
- else
- tf = resident_font[fontnum];
- }
- else
- tf = resident_font[fontnum];
- }
- else {
- if ((tf = get_font(kanji)) == NULL) {
- tf = resident_font[SYM1];
- code = KNJ_ILGL;
- }
- }
- if (current_font != tf) {
- Text(rport, strbuff, strlen(strbuff));
- strbuff[0] = NUL;
- current_font = tf;
- SetFont(rport, current_font);
- current_x = rport->cp_x;
- }
-
- if ((current_x += current_font->tf_XSize) >= Wind->Width)
- handle_ctrl_code(LF);
- strncat(strbuff, &code, sizeof(char));
- }
-
-
- VOID handle_ctrl_code(int code)
- {
- Text(rport, strbuff, strlen(strbuff));
- strbuff[0] = NUL;
-
- switch (code) {
- case LF:
- current_x = Wind->BorderLeft;
- current_y += FONT_SIZE;
- Move(rport, current_x, current_y);
- count[++current_line] = 0;
- break;
- case TAB:
- current_x = tabalign(rport->cp_x, resident_font[ANK]->tf_XSize);
- Move(rport, current_x, current_y);
- break;
- default:
- break;
- }
- }
-
-
- char *strchr_r(char *str, int c)
- {
- while (*str != c)
- str--;
-
- return str;
- }
-
-
- #define forward_scroll(rport) (ScrollRaster((rport), 0, FONT_SIZE, \
- Wind->BorderLeft, Wind->BorderTop, \
- Wind->Width, Wind->Height - FONT_SIZE - 1))
- #define backward_scroll(rport) (ScrollRaster((rport), 0, -FONT_SIZE, \
- Wind->BorderLeft, Wind->BorderTop, \
- Wind->Width, Wind->Height - FONT_SIZE - 1))
- #define clear_screen(rport) (SetRast((rport), 0))
-
- int keyin_loop(LONG *point, int nbyte, char *mes)
- {
- int retval = NORMAL;
-
- switch (print_message(mes)) {
- case QUIT_PRG:
- retval = QUIT;
- break;
- case LINE_SCROLL:
- current_y -= FONT_SIZE;
- Move(rport, current_x, current_y);
- forward_scroll(rport);
- top_line++;
- break;
- case BACK_LINE:
- current_y = Wind->BorderTop + rport->TxBaseline;
- Move(rport, current_x, current_y);
- if (top_line > 0) {
- backward_scroll(rport);
- top_line--;
- }
- retval = count_bytes(point, nbyte);
- break;
- case BACK_SCROLL:
- current_y = Wind->BorderTop + rport->TxBaseline;
- Move(rport, current_x, current_y);
- clear_screen(rport);
- top_line = (top_line > TOTAL_LINES) ?
- top_line - TOTAL_LINES : 0;
- retval = count_bytes(point, nbyte);
- break;
- case PAGE_SCROLL:
- default:
- current_y = Wind->BorderTop + rport->TxBaseline;
- Move(rport, current_x, current_y);
- clear_screen(rport);
- top_line = current_line;
- break;
- }
-
- return retval;
- }
-
-
- int print_message(char *mes)
- {
- struct TextFont *tf = current_font;
- int x, y;
- char strbuf[STRBUFSIZE];
-
- x = Wind->BorderLeft;
- y = Wind->Height - FONT_SIZE + rport->TxBaseline;
- Move(rport, x, y);
-
- current_font = resident_font[ANK];
- SetFont(rport, current_font);
-
- sprintf(strbuf, mes, in_fname);
- SetDrMd(rport, JAM2|INVERSVID);
- Text(rport, strbuf, strlen(strbuf));
- SetDrMd(rport, JAM2);
-
- current_font = tf;
- SetFont(rport, current_font);
-
- return handle_rawkey();
- }
-
-
- int handle_rawkey(VOID)
- {
- BOOL done = FALSE;
- int retval;
- struct IntuiMessage *msg;
-
- while (!done) {
- WaitPort(Wind->UserPort);
- while (msg = (struct IntuiMessage *)GetMsg(Wind->UserPort)) {
- ReplyMsg((struct Message *)msg);
- switch (msg->Class) {
- case RAWKEY:
- switch (msg->Code) {
- case QUIT_PRG:
- case LINE_SCROLL:
- case BACK_LINE:
- case PAGE_SCROLL:
- case BACK_SCROLL:
- retval = msg->Code;
- done = TRUE;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- }
-
- return retval;
- }
-
-
- int count_bytes(LONG *point, int nbyte)
- {
- int sum = 0;
-
- do {
- sum += count[--current_line];
- } while (current_line != top_line);
-
- count[current_line] = 0;
-
- if (sum > nbyte)
- return sum - nbyte;
- else {
- *point -= sum;
- return NORMAL;
- }
- }
-
-
- VOID fseek_back(int nbyte)
- {
- if (fseek(infile, -nbyte, SEEK_CUR) != 0)
- clean_exit("fseek error !", RETURN_FAIL);
- }
-
-
- /* initialize the jFontMsg structure */
- VOID init_myMsg(VOID)
- {
- struct jFontMsg *msg = &fontMsg;
-
- msg->msg.mn_Node.ln_Type = NT_MESSAGE;
- msg->msg.mn_Length = sizeof(struct jFontMsg);
- msg->msg.mn_ReplyPort = init_myport();
- }
-
-
- /* initialize the MsgPort for ReplyMsg */
- struct MsgPort *init_myport(VOID)
- {
- if (FindPort(JMOREPORT) == NULL) {
- if ((jMorePort = CreatePort(JMOREPORT, NORMAL_PRI)) != NULL)
- return jMorePort;
- }
- clean_exit("jMore is already used.", RETURN_FAIL);
-
- return (struct MsgPort *)NULL; /* but not reached here */
- }
-
-
- struct TextFont *get_font(USHORT kanji)
- {
- struct MsgPort *mPort;
- struct jFontMsg *msg = &fontMsg;
-
- msg->kanji = kanji;
- Forbid();
- if ((mPort = FindPort(JFONTPORT)) == NULL)
- clean_exit("jFontSys is not installed !", RETURN_FAIL);
- PutMsg(mPort, (struct Message *)msg);
- Permit();
-
- WaitPort(jMorePort);
- msg = (struct jFontMsg *)GetMsg(jMorePort);
-
- return msg->font;
- }
-
-
- struct TextFont *init_resident_font(VOID)
- {
- int i;
-
- for (i = SYM1; i <= KATA; i++)
- resident_font[i] = get_font((USHORT)((i + ' ')<<CHAR_BIT));
-
- return (resident_font[ANK] = get_font((USHORT)ANK_FONT_CODE));
- }
-
-
- /* ScrnDefn & WindDefn is declere in jmore.h */
- VOID OpenScrnWind(VOID)
- {
- if ((Scrn = (struct Screen *)OpenScreen(&ScrnDefn)) == NULL)
- clean_exit("No Screen !", RETURN_FAIL);
- ShowTitle(Scrn, FALSE);
-
- WindDefn.Screen = Scrn;
- if ((Wind = (struct Window *)OpenWindow(&WindDefn)) == NULL)
- clean_exit("No Window !", RETURN_FAIL);
-
- rport = Wind->RPort;
- }
-
-
- FILE *fset(char *fname, char *mode)
- {
- FILE *fp;
-
- if ((fp = fopen(fname, mode)) == NULL)
- clean_exit(strcat(fname, " not open !"), RETURN_FAIL);
-
- return fp;
- }
-
-
- VOID clean_exit(char *mes, int extval)
- {
- if (Wind)
- CloseWindow(Wind);
- if (Scrn)
- CloseScreen(Scrn);
- CloseLib();
-
- if (jMorePort)
- DeletePort(jMorePort);
-
- if (infile)
- fclose(infile);
-
- if (olddir)
- CurrentDir(olddir);
-
- if (*mes)
- fprintf(stderr, "%s\n", mes);
-
- exit(extval);
- }
-
-
- VOID usage(VOID)
- {
- puts(ERROR_MESSAGE);
- exit(EXIT_FAILURE);
- }
-
-
- /* for startup file routine */
- VOID get_startup(VOID)
- {
- FILE *fp;
-
- if ((fp = fopen(STARTUP, READ_BINARY)) != NULL) {
- while (set_startup_value(fp) != EOF)
- ;
- fclose(fp);
- }
- }
-
-
- int set_startup_value(FILE *fp)
- {
- char *lp, *name_end, *value_head;
- int c;
-
- lp = my_getline(fp);
- if ((name_end = strchr(lp, '=')) != NULL) {
- value_head = name_end + 1;
- if (strncmp(startup[TAB_WIDTH], lp, name_end - lp) == 0) {
- tabspc = atoi(value_head);
- }
- }
- else if (strlen(lp) > 0) {
- if (strcmp(startup[REGULAR], lp) == 0) {
- regular = TRUE;
- }
- }
- c = fgetc(fp);
- ungetc(c, fp); /* for check EOF */
-
- return c;
- }
-
-
- #define LINEBUFLEN 80
-
- char *my_getline(FILE *fp)
- {
- int c, iscomment = FALSE;
- static char linebuf[LINEBUFLEN], *lp;
-
- lp = linebuf;
- while ((c = fgetc(fp)) != LF && c != EOF) {
- if (!iscomment && isgraph(c)) {
- switch (c) {
- case COMMENT_MARK:
- iscomment = TRUE;
- break;
- default:
- if (islower(c))
- c = toupper(c);
- *lp++ = (char)c;
- break;
- }
- }
- }
- *lp = NUL;
-
- return linebuf;
- }
-